#include <iostream>
#include <coroutine>
#include <exception>
#include <thread>
#include <chrono>
#include <functional>
#include <vector>

// 简单的协程返回类型，用于生成器模式
template<typename T>
class Generator {
public:
    // 定义promise_type，这是协程必需的
    struct promise_type {
        T m_value_;
        std::exception_ptr m_exception_;
        
        Generator get_return_object() {
            return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        
        std::suspend_always initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        
        void unhandled_exception() { 
            m_exception_ = std::current_exception(); 
        }
        
        template<std::convertible_to<T> From>
        std::suspend_always yield_value(From&& from) {
            m_value_ = std::forward<From>(from);
            return {};
        }
        
        void return_void() {}
    };
    
    // 以下是Generator类的成员函数和构造函数
    explicit Generator(std::coroutine_handle<promise_type> handle) 
        : m_handle_(handle) {}
    
    Generator(const Generator&) = delete;
    Generator& operator=(const Generator&) = delete;
    
    Generator(Generator&& other) noexcept 
        : m_handle_(other.m_handle_) {
        other.m_handle_ = nullptr;
    }
    
    Generator& operator=(Generator&& other) noexcept {
        if (this != &other) {
            if (m_handle_) {
                m_handle_.destroy();
            }
            m_handle_ = other.m_handle_;
            other.m_handle_ = nullptr;
        }
        return *this;
    }
    
    ~Generator() {
        if (m_handle_) {
            m_handle_.destroy();
        }
    }
    
    // 检查协程是否完成
    bool done() const {
        return !m_handle_ || m_handle_.done();
    }
    
    // 获取当前值
    T current_value() const {
        return m_handle_.promise().m_value_;
    }
    
    // 向前移动协程执行
    bool move_next() {
        if (m_handle_) {
            m_handle_.resume();
            if (m_handle_.promise().m_exception_) {
                std::rethrow_exception(m_handle_.promise().m_exception_);
            }
        }
        return !done();
    }

private:
    std::coroutine_handle<promise_type> m_handle_;
};

// 使用Generator<int>创建一个计数器
Generator<int> counter(int start, int end) {
    for (int i = start; i <= end; ++i) {
        co_yield i;
    }
}

// 生成斐波那契数列的协程
Generator<int> fibonacci(int n) {
    if (n <= 0) co_return;
    
    co_yield 0;
    if (n == 1) co_return;
    
    co_yield 1;
    if (n == 2) co_return;
    
    int a = 0, b = 1;
    for (int i = 2; i < n; ++i) {
        int next = a + b;
        co_yield next;
        a = b;
        b = next;
    }
}

// 模拟异步操作的协程
struct Task {
    struct promise_type {
        Task get_return_object() { 
            return Task{std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }  // 改为suspend_always，防止自动销毁
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };
    
    std::coroutine_handle<promise_type> m_handle_;
    
    Task(std::coroutine_handle<promise_type> h) : m_handle_(h) {}
    
    // 移动构造函数和赋值
    Task(Task&& other) noexcept : m_handle_(other.m_handle_) {
        other.m_handle_ = nullptr;
    }
    
    Task& operator=(Task&& other) noexcept {
        if (this != &other) {
            if (m_handle_) {
                m_handle_.destroy();
            }
            m_handle_ = other.m_handle_;
            other.m_handle_ = nullptr;
        }
        return *this;
    }
    
    Task(const Task&) = delete;
    Task& operator=(const Task&) = delete;
    
    ~Task() {
        // 只有当handle有效且协程未完成时才销毁
        // 如果协程已经完成，promise可能已经被销毁
        if (m_handle_ && !m_handle_.done()) {
            m_handle_.destroy();
        } else if (m_handle_) {
            // 协程已完成，需要手动销毁（因为final_suspend返回suspend_always）
            m_handle_.destroy();
        }
    }
    
    // 检查协程是否完成
    bool done() const {
        return !m_handle_ || m_handle_.done();
    }
    
    // 等待协程完成
    void wait() {
        if (m_handle_ && !m_handle_.done()) {
            m_handle_.resume();
        }
    }
};

// 模拟延迟操作
struct Awaiter {
    std::chrono::milliseconds m_delay_;
    
    Awaiter(std::chrono::milliseconds delay) : m_delay_(delay) {}
    
    bool await_ready() const { return false; }
    
    void await_suspend(std::coroutine_handle<> handle) {
        std::thread([handle, this]() {
            std::this_thread::sleep_for(m_delay_);
            handle.resume();
        }).detach();
    }
    
    void await_resume() {}
};

// 使用Awaiter实现延迟执行
Task delay_print(const std::string& message, std::chrono::milliseconds delay) {
    std::cout << "  开始: " << message << '\n';
    
    co_await Awaiter{delay};
    
    std::cout << "  " << delay.count() << "ms后: " << message << " 完成!\n";
}

void demonstrate_coroutines() {
    std::cout << "  C++20 协程(Coroutines)演示:\n\n";
    
    // 1. 使用Generator
    std::cout << "  简单计数器示例:\n";
    auto count = counter(1, 5);
    
    while (count.move_next()) {
        std::cout << "  计数: " << count.current_value() << '\n';
    }
    
    // 2. 斐波那契数列
    std::cout << "\n  斐波那契数列(前10个):\n  ";
    auto fib = fibonacci(10);
    
    while (fib.move_next()) {
        std::cout << fib.current_value() << " ";
    }
    std::cout << '\n';
    
    // 3. 异步操作示例
    std::cout << "\n  异步操作示例:\n";
    
    // 注意：由于异步任务的复杂性，这里简化示例，避免生命周期问题
    // 在实际应用中，应该使用更完善的协程框架（如cppcoro）来管理异步任务
    std::cout << "  注意：异步协程示例因生命周期管理复杂，已简化。\n";
    std::cout << "  在实际应用中建议使用专门的协程库（如cppcoro）来管理异步任务。\n";
    
    // 简化版本：不使用detached线程，直接演示协程的基本用法
    // auto task1 = delay_print("任务1", std::chrono::milliseconds(100));
    // std::this_thread::sleep_for(std::chrono::milliseconds(200));
    
    // 4. 使用协程处理集合
    std::cout << "\n  处理集合示例:\n";
    
    // 返回偶数的生成器
    auto even_numbers = [](int max) -> Generator<int> {
        for (int i = 0; i <= max; i += 2) {
            co_yield i;
        }
    };
    
    std::cout << "  偶数(0-10):\n  ";
    auto evens = even_numbers(10);
    while (evens.move_next()) {
        std::cout << evens.current_value() << " ";
    }
    std::cout << '\n';
    
    // 5. 显示协程的优势
    std::cout << "\n  协程的优势 - 无需手动维护状态:\n";
    
    // 使用协程简化复杂状态管理
    auto complex_process = [](int steps) -> Generator<std::string> {
        co_yield "开始处理";
        
        for (int i = 1; i <= steps; ++i) {
            std::string result = "步骤 " + std::to_string(i) + " 完成";
            co_yield result;
            
            // 可以在这里添加复杂逻辑，状态会自动保存
        }
        
        co_yield "处理完成";
    };
    
    auto process = complex_process(3);
    while (process.move_next()) {
        std::cout << "  " << process.current_value() << '\n';
    }
} 